package wangxiaotao.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import wangxiaotao.aop.annotation.Log;
import wangxiaotao.bean.dto.PasswordDTO;
import wangxiaotao.bean.vo.UserVO;
import wangxiaotao.common.CommonResult;
import wangxiaotao.converter.UserConverter;
import wangxiaotao.entity.User;
import wangxiaotao.entity.UserRoleRel;
import wangxiaotao.tools.ConstValue;
import wangxiaotao.utils.JWTUtils;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/admin/user")
public class AdminUserController extends BaseController{
    private final ConstValue constValue;
    private final UserConverter userConverter;

    /**
     * 获取用户自己的信息 不包括角色信息
     * @return
     */
    @RequiresAuthentication//需要认证
    @GetMapping("")
    public CommonResult getUserInfoByMySelf() {
        Object principal = SecurityUtils.getSubject().getPrincipal();
        String id = JWTUtils.getClaimByName((String) principal, "id");
        User user = userService.getOne(new QueryWrapper<User>().eq("id", id));
        return CommonResult.success(userConverter.toUserVO(user));
    }
    /**
     * 获取所有用户信息 包括角色信息
     * 模糊查询数据也在这个接口
     * @return
     */
    @RequiresPermissions({"user:list"})
    @GetMapping("/list")
    @Log
    public CommonResult queryAllUserInfoAndRole(String type, String data) {
        return CommonResult.success(adminService.queryAllUserInfoAndRole(getPage(),type,data));
    }

    /**
     * 修改用户信息
     * @param userVO
     * @return
     */
    @RequiresPermissions({"user:update"})
    @PostMapping("/update")
    @Log
    public CommonResult updateUser(@RequestBody UserVO userVO) {
        User user = userConverter.toUser(userVO);
        if (userService.updateById(user))
            return CommonResult.success();
        return CommonResult.fail();
    }

    /**
     * 修改用户的角色信息 包括移除和增加权限
     * @param userId
     * @param setRoleIds
     * @return
     */
    @RequiresPermissions({"user:update"})
    @PostMapping("/role/update/{userId}")
    @Transactional
    @Log
    public CommonResult updateRole(@PathVariable Integer userId, @Validated @RequestBody Integer[] setRoleIds) {
        List<Integer> hasRoles = userRoleRelService.listObjs(new QueryWrapper<UserRoleRel>().select("role_id").eq("user_id", userId), s -> (Integer) s);
        List<UserRoleRel> setRoles = Arrays.stream(setRoleIds).map(s -> new UserRoleRel(userId, s)).collect(Collectors.toList());
        if (!hasRoles.isEmpty())
            userRoleRelService.remove(new QueryWrapper<UserRoleRel>().in("role_id", hasRoles).eq("user_id", userId));
        if (!setRoles.isEmpty())
            userRoleRelService.saveBatch(setRoles);
        return CommonResult.success();
    }

    /**
     * 管理员权限下新增用户
     * @param userVO
     * @return
     */
    @RequiresPermissions({"user:add"})
    @PostMapping("/add")
    @Log
    public CommonResult userAdd(@Validated @RequestBody UserVO userVO) {
        Long count = userService.getObj(new QueryWrapper<User>().select("count(1)").eq("username", userVO.getUsername()), s -> (long) s);
        Assert.isTrue(count==0,"用户名已经存在，请重新填写");
        Assert.isTrue(userService.userAdd(userVO)>0,"用户添加失败");
        return CommonResult.success();
    }


    /**
     * 批量禁用 批量启用账户
     * @param userIds
     * @return
     */
    @RequiresPermissions({"user:update"})
    @PostMapping("/bachStatue/{statue}")
    @Log
    public CommonResult userBeachDisable(@PathVariable Boolean statue,@RequestBody Integer[] userIds) {
        List<User> userList = Arrays.stream(userIds).map(s -> (User) new User().setStatue(statue).setId(s)).collect(Collectors.toList());
        if (userService.updateBatchById(userList))
            return CommonResult.success();
        return CommonResult.fail();
    }


    /**
     * 设置用户密码 update(T t,Wrapper updateWrapper)时t不能为空,否则自动填充失效
     * @return
     */
    @RequiresPermissions({"user:update"})
    @PostMapping("/updatePassword")
    @Log
    public CommonResult updatePasswordByUserId(@Validated @RequestBody PasswordDTO passwordDTO) {
        if (userService.update((User) new User().setId(passwordDTO.getId()),new UpdateWrapper<User>().eq("id", passwordDTO.getId()).set("password", passwordDTO.getPassword())))
            return CommonResult.success();
        return CommonResult.fail();
    }

    /**
     * 批量重置密码
     * @param userIds
     * @return
     */
    @RequiresPermissions({"user:update"})
    @PostMapping("/bachRestPassword")
    @Log
    public CommonResult beachRestPassword(@RequestBody Integer[] userIds) {
        List<User> userList = Arrays.stream(userIds).map(s -> (User)new User().setPassword(constValue.getDefaultPassword()).setId(s)).collect(Collectors.toList());
        if (userService.updateBatchById(userList))
            return CommonResult.success(constValue.getDefaultPassword());
        return CommonResult.fail();
    }

    /**
     * 用户修改自己的信息
     * @return
     */
    @RequiresAuthentication
    @PostMapping("/updateMySelf")
    @Log
    public CommonResult updateMySelf(@RequestParam(value = "userAvatar",required = false) MultipartFile[] file,@Validated UserVO userVO){
        User user = userConverter.toUser(userVO);
        if (file!=null){
            String userAvatar = minioTool.saveUserImage(file, userVO.getUsername());
            user.setAvatar(userAvatar);
        }
        if (userService.updateById(user))
            return CommonResult.success();
        return CommonResult.fail();
    }
}
